iT邦幫忙

2026 iThome 鐵人賽

DAY 1
2
Vibe Coding

做一個團購後端,順便搞懂那些事系列 第 1

Day 1|先來點 README:PayPool 在做什麼

  • 分享至 

  • xImage
  •  

基本介紹

PayPool 是一套團購記帳管理系統的後端 API,整個專案的核心流程用一句話概括就是:一人開團、多人下單、截止時間到自動從各人帳戶餘額扣款、結果即時通知。
這次使用的技術棧為:Java 25、Spring Boot 3.5、MySQL、MyBatis-Plus、Spring Security + JWT(RS256)、Redis、WebSocket(STOMP)、Flyway。

後面30天會頻繁出現以下七個詞,先在這邊解釋一下。

名詞 定義
團主 開團者,即建立訂單的帳號
團購訂單 一次開團的整體,含名稱、截止時間、狀態
品項 某人在某張訂單裡點的東西(小美的大杯珍奶 ×1)
截止時間 開團時決定,到期自動關單並結算
結算 逐一從各人餘額扣款並寫入流水帳
餘額 帳戶實際金額
可用餘額 餘額減去未結算的凍結金額,不存 DB,即時計算

餘額與可用餘額為何分開?

小明餘額 500,在三張未結算訂單中各點了 200。若下單檢查只看實際餘額,三次都會通過(每次都看到 500),如果三張訂單同時到期,那小明的帳戶就會爆掉了。

因此兩者用途不同:下單時檢查的是"可用餘額",結算時實際扣款扣的是"餘額"。

可用餘額 = balance - SUM(OPEN 與 FAILED 訂單中該使用者的品項小計)

一張訂單會經過哪些狀態?

https://ithelp.ithome.com.tw/upload/images/20260914/20168667RhQgWJce5a.png

FAILED 既非成功也非結束:錢沒扣到,但補足餘額之後仍可回到主流程,只是回到主流程並不是自動觸發的——訂單會停在 FAILED,要有人再呼叫一次結算api,對同一張訂單重跑整段扣款流程。
相反的,如果訂單上全部的人都足額就轉 SETTLED


流程只是 CRUD? 陷阱在哪裡?

開團、下單、扣款,每一步都是 CRUD。

服務本身是單體架構,但設計上假設會有多個實例同時在跑,MySQL 與 Redis 是所有實例共用的外部服務。難的是這五個問題:

  • 「截止時間到」由誰觸發?服務重啟後未到期的訂單還會被結算嗎?
  • 同一個人參加的兩張單同時到期結算,餘額只夠付一張,會被扣成負數嗎?
  • 扣款扣到一半失敗,已扣的錢如何回復?
  • 兩台機器跑同一套服務,同一張單會不會被結算兩次?
  • 連在 A 機器的使用者,收得到 B 機器發出的 WebSocket 通知嗎?

用AI搭配規格驅動開發

這次專案選擇以 AI 輔助開發,流程採用 **SDD(Spec-Driven Development)**模式,使用OpenSpec進行開發:先有規格,人審過規格後 AI 才照規格實作,實作完再對照規格審查。

下面這四個Skill串起了整個開發流程,從討論規格定義以及實作的邊界,根據討論結果寫出proposal(規格提案,其中包含測試的規格),再開始按照task.md的任務清單進行實作。規格先定義清楚,AI 再動手開發。

指令 做什麼
/opsx:explore 釐清需求,只討論不動手
/opsx:propose 產出四份規劃文件(design.md, proposal.md, tasks.md, spec.md),不碰程式碼
/opsx:apply tasks.md 逐項實作
/opsx:archive 歸檔,並可把這次的 spec 同步進 openspec/specs/ 主規格

每次的propose會先產出四份規劃文件:

文件 回答什麼
proposal.md 要做什麼、為什麼做
specs/*/spec.md 系統必須有什麼行為,寫成 WHEN / THEN 情境
design.md 怎麼做,每個設計決策編號記錄(D1、D2⋯)
tasks.md 實作步驟,每項依 TDD 拆成 RED / GREEN

以權限系統為例,spec 的情境:

#### Scenario: 無權限的操作被拒絕

- **WHEN** 角色「團長」未被允許「刪除其他人帳號」,且僅擁有團長角色的使用者呼叫該功能
- **THEN** 系統回覆 HTTP 403,錯誤訊息明確表達「權限不足」(而非「未登入」)
- **AND** 沒有任何資料被異動

對應的 tasks,測試先於實作:

- [x] 3.1 RED:`DynamicAuthorizationManager` 單元測試——未認證 deny、SUPER_ADMIN 放行、URL pattern 命中且有權限放行、命中但無權限 deny、未登記端點放行、多角色取聯集、method 比對(含 ALL)
- [x] 3.2 GREEN:實作 `DynamicAuthorizationManager`(PathPatternParser 比對,依 design.md D2 判斷順序)

到目前為止,SDD不只幫忙提前想到我沒想到的邊界問題,也讓我可以掌控AI開發出來最後的結果,避免AI自由發揮XD


下一篇
Day 2|一個請求的完整旅程
系列文
做一個團購後端,順便搞懂那些事8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言